package com.jwcao.common.cast.annotation.factory;

import com.jwcao.common.cast.Cast;
import com.jwcao.common.cast.annotation.CastObject;

import java.util.ArrayList;
import java.util.Arrays;
import java.util.List;

import com.jwcao.common.utils.ReflectUtil;
import org.apache.commons.lang3.ArrayUtils;
import org.apache.commons.lang3.StringUtils;

/**
 * name: CastObjectFactory description: TODO
 *
 * @author caojingwei date: 2023/3/24 16:57
 */
public class CastObjectFactory {

    public static List<CastObject> get(Class clazz) {

        List<CastObject> castObjectList = new ArrayList<>();
        CastObject[] casts = (CastObject[]) clazz.getDeclaredAnnotationsByType(CastObject.class);
//        return ReflectUtil.getInheritedDeclaredAnnotation(clazz, CastObject.class);
        return Arrays.asList(casts);
    }

    public static Class getClass(CastObject castObject) {
        Class targetClass = castObject.value();
        if (targetClass == Object.class) {
            //TODO:: 这里要检测一下报错信息
            try {
                targetClass = Class.forName(castObject.className());
            } catch (ClassNotFoundException e) {
                e.printStackTrace();
                throw new RuntimeException(e);
            }
        }
        return targetClass;
    }

    public static CastObject get(String id, Class sourceClas, Class targetClass) {
//        if (!(aClass.isAnnotationPresent(Casts.class) || aClass.isAnnotationPresent(Cast.class))) {
//            return null;
//        }
        CastObject[] casts = (CastObject[]) sourceClas.getAnnotationsByType(CastObject.class);
        if (ArrayUtils.isEmpty(casts)) {
            return null;
        }
        return Arrays.stream(casts)
                //此处判断转换条件不够严谨(注解中需填转换的class)，可能会出现问题
                .filter(c -> {
                    Class clazz = getClass(c);
                    return clazz == targetClass || clazz.isAssignableFrom(targetClass)
                            || targetClass.isAssignableFrom(clazz);
                })
                .filter(c -> {
                    // 如果 id 是空的，那么这么就不需要检查
                    if (StringUtils.isNotEmpty(id)) {
                        return StringUtils.equals(c.id(), id);
                    }
                    return true;
                })
                .findAny()
                .orElse(null);
    }
}
